home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / XPK / Source / prefs / XpkMasterPrefs.c < prev   
Encoding:
C/C++ Source or Header  |  1997-06-18  |  16.4 KB  |  620 lines

  1. #define NAME     "XpkMasterPrefs"
  2. #define REVISION "16"
  3. //#define DEBUG
  4.  
  5. /* Programmheader
  6.  
  7.     Name:        XpkMasterPrefs
  8.     Author:        SDI
  9.     Distribution:    PD
  10.     Description:    xpk prefs loader, like IPrefs
  11.     Compileropts:    -
  12.     Linkeropts:    -gsi (no startup)
  13.  
  14.  1.0   25.12.96 : first Version
  15.  1.1   26.12.96 : nearly redefined xpkprefs structures - a lot of changes
  16.  1.2   27.12.96 : some fixes
  17.  1.3   30.12.96 : did a bit on Recog function
  18.  1.4   02.01.97 : added correctness check of BufPattern
  19.  1.5   11.01.97 : corrected some errors
  20.  1.6   28.02.97 : changed some semaphore specific stuff
  21.  1.7   01.03.97 : added Version info to MainPrefs
  22.  1.8   07.03.97 : fixed RecogFunc
  23.  1.9   24.03.97 : added DEBUG stuff
  24.  1.10  28.03.97 : added last function and ReadArgs
  25.  1.11  02.04.97 : XpkTypeData changed, ListData now internal structure
  26.  1.12  03.04.97 : added DEBUG info, debuged RecogFunction
  27.  1.13  04.04.97 : buffer now 2 K
  28.  1.14  06.06.97 : name pattern no case independant
  29.  1.15  17.06.97 : fixed error, when no name and no filepattern
  30.  1.16  18.06.97 : added filelength check and OR parameter
  31. */
  32.  
  33. /*
  34. How to parse the type list:
  35. - The struct XpkTypeData of the first matching structure is returned.
  36. - If no type matches, the default is returned.
  37. - Scan goes always in linear order from the beginning to end. (and never
  38.   reverse).
  39. - if no file name is given, the xtp_FilePattern field is ignored.
  40. */
  41.  
  42. #include <pragma/exec_lib.h>
  43. #include <pragma/dos_lib.h>
  44. #include <pragma/iffparse_lib.h>
  45. #include <prefs/prefhdr.h>
  46. #include <xpk/xpkprefs.h>
  47. #include <exec/memory.h>
  48. #include "SDI_defines.h"
  49. #define SDI_TO_ANSI
  50. #include "SDI_ASM_STD_protos.h"
  51.  
  52.  
  53. /**************************************************************************
  54.  *
  55.  * Standard prefs specific data structure. xps_PrefsData points to this.
  56.  *
  57.  * xssd_TypeList nodes are of type XpkTypeNode.
  58.  *
  59.  * 
  60.  */
  61.  
  62. struct XpkStdSemaphoreData {
  63.   struct List    xssd_TypeList;     /* list of file types */
  64.   ULONG        xssd_Buffer1Size;  /* size of following buffer */
  65.   STRPTR    xssd_Buffer1;       /* pointer to buffer */
  66. };
  67.  
  68. struct XpkTypeNode {
  69.   struct Node        xtn_Node;    /* standard node structure */
  70.   ULONG            xtn_Size;    /* hold complete size to free */
  71.   struct XpkTypePrefs    xtn_TypePrefs;  /* real data */
  72. };
  73.  
  74. #define RECOGBUFSIZE    2048
  75.  
  76. #define PARAM "QUIT/S"
  77.  
  78. #ifdef __MAXON__
  79.   #define __asm
  80.   struct Library *IFFParseBase;
  81. #else
  82.   #define iffparsebase    IFFParseBase
  83. #endif
  84.  
  85. struct DosLibrary *DOSBase;
  86.  
  87. void CorrectAdr(APTR pos, APTR mempos);
  88. void DoPrefsCreation(struct XpkPrefsSemaphore *sem);
  89. void ClearTypeList(struct XpkStdSemaphoreData *sem);
  90. void ClearMainPrefs(struct XpkPrefsSemaphore *sem);
  91. struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
  92. register __a1 STRPTR name, register __a2 STRPTR printname,
  93. register __d0 ULONG bufsize, register __d1 ULONG fullsize);
  94.  
  95. UBYTE CheckHex(STRPTR *data, LONG number);
  96. ULONG CheckBufPattern(STRPTR pattern);
  97. UBYTE GetCharacter(STRPTR pattern);
  98. /* these two return zero, when name matches or defined values, when not */
  99. ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
  100. ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize);
  101. ULONG MatchFileName(STRPTR pattern, STRPTR name);
  102.  
  103. #define MATCHERR_PATTERN_INCORRECT    1
  104. #define MATCHERR_NO_MEMORY        2
  105. #define MATCHERR_BUFFER_TO_SHORT    3
  106. #define MATCHERR_NO_MATCH        4
  107. #define MATCHERR_NO_SIZE_MATCH        5
  108.  
  109. ULONG start(void) /* not named main, to get error with startup code ! */
  110. {
  111.   struct DosLibrary *dosbase;
  112.   struct XpkPrefsSemaphore *semaphore;
  113.   struct Process *task;
  114.   struct Message *msg = 0;
  115.   struct RDArgs *rda;
  116.   LONG quit = 0;
  117.  
  118.   if(!(task = (struct Process *) FindTask(0))->pr_CLI)
  119.   {
  120.     WaitPort(&task->pr_MsgPort);
  121.     msg = GetMsg(&task->pr_MsgPort);
  122.     /* no tooltype check now, so means always start semaphore */
  123.   }
  124.   else
  125.   {
  126.     if((dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  127.     {
  128.       DOSBase = dosbase;
  129.       if((rda = ReadArgs(PARAM, &quit, 0)))
  130.         FreeArgs(rda);
  131.       CloseLibrary((struct Library *) dosbase);
  132.     }
  133.     /* does not recognize failed ReadArgs - normal start in this case */
  134.   }
  135.  
  136.   if(quit)
  137.   {
  138.     Forbid();
  139.     if((semaphore = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME)))
  140.     {
  141.       ObtainSemaphoreShared((struct SignalSemaphore *) semaphore);
  142.         Signal(semaphore->xps_MasterTask, SIGBREAKF_CTRL_C);
  143.       ReleaseSemaphore((struct SignalSemaphore *) semaphore);
  144.     }
  145.     Permit();
  146.   }
  147.   else if(!FindSemaphore(XPKPREFSSEMNAME) &&
  148.   (dosbase = (struct DosLibrary *) OpenLibrary("dos.library", 37)))
  149.   {
  150.     DOSBase = dosbase;
  151.     if((semaphore = (struct XpkPrefsSemaphore *) AllocMem(sizeof(struct
  152.     XpkPrefsSemaphore) + sizeof(struct XpkStdSemaphoreData), MEMF_PUBLIC|MEMF_CLEAR)))
  153.     {
  154.       struct NotifyRequest *notifyrequest;
  155.  
  156.       struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *)
  157.        (((STRPTR) semaphore) + sizeof(struct XpkPrefsSemaphore));
  158.         // both structures are allocated with one AllocMem
  159.  
  160.       semaphore->xps_Semaphore.ss_Link.ln_Type = NT_SEMAPHORE;
  161.       semaphore->xps_Semaphore.ss_Link.ln_Name = XPKPREFSSEMNAME;
  162.       semaphore->xps_PrefsData = sd;
  163. //    semaphore->xps_Version = 0;
  164.       semaphore->xps_PrefsType = XPREFSTYPE_STANDARD;
  165. //    semaphore->xps_ProgressFunc = 0;
  166.       semaphore->xps_RecogSize = RECOGBUFSIZE;
  167.       semaphore->xps_RecogFunc = (struct XpkTypeData *(*)()) RecogFunc;
  168.       semaphore->xps_MasterTask = (struct Task *) task;
  169.  
  170.       sd->xssd_TypeList.lh_Type = NT_USER;
  171.       sd->xssd_TypeList.lh_Head = (struct Node *) &sd->xssd_TypeList.lh_Tail;
  172.       sd->xssd_TypeList.lh_TailPred = (struct Node *) &sd->xssd_TypeList.lh_Head;
  173.  
  174.       InitSemaphore((struct SignalSemaphore *) semaphore);
  175.       AddSemaphore((struct SignalSemaphore *) semaphore);
  176.  
  177.       if((notifyrequest = (struct NotifyRequest *)
  178.       AllocMem(sizeof(struct NotifyRequest), MEMF_CLEAR)))
  179.       {
  180.         ULONG signr;
  181.  
  182.         if((signr = AllocSignal(-1L)) != -1)
  183.         {
  184.           notifyrequest->nr_Name = "ENV:xpkmaster.prefs";
  185.           notifyrequest->nr_Flags = NRF_SEND_SIGNAL | NRF_NOTIFY_INITIAL;
  186.           notifyrequest->nr_stuff.nr_Signal.nr_Task = FindTask(0);
  187.           notifyrequest->nr_stuff.nr_Signal.nr_SignalNum = signr;
  188.           if((StartNotify(notifyrequest)) == DOSTRUE)
  189.           {
  190.         ULONG signal = 0;
  191.             while(!(signal & SIGBREAKF_CTRL_C))
  192.               if((signal = Wait(1 << signr | SIGBREAKF_CTRL_C)) & (1 << signr))
  193.             DoPrefsCreation(semaphore);
  194.             EndNotify(notifyrequest);
  195.           }
  196.           FreeSignal(signr);
  197.         }
  198.         FreeMem(notifyrequest, sizeof(struct NotifyRequest));
  199.       }
  200.       ObtainSemaphore((struct SignalSemaphore *) semaphore);
  201.       RemSemaphore((struct SignalSemaphore *) semaphore);
  202.       ClearTypeList((struct XpkStdSemaphoreData *) semaphore->xps_PrefsData);
  203.       ClearMainPrefs(semaphore);
  204.  
  205.       FreeMem(semaphore, sizeof(struct XpkPrefsSemaphore) +
  206.         sizeof(struct XpkStdSemaphoreData));
  207.     }
  208.     CloseLibrary((struct Library *) dosbase);
  209.   }
  210.  
  211.   if(msg)
  212.   {
  213.     Forbid();
  214.     ReplyMsg(msg);
  215.   }
  216.  
  217.   return 0;
  218. }
  219.  
  220. /* changes relative addresses into normal ones */
  221. void CorrectAdr(APTR pos, APTR mempos)
  222. {
  223.   if(*(ULONG *)pos)
  224.     *(ULONG *)pos += (ULONG) mempos;
  225. }
  226.  
  227. void ClearTypeList(struct XpkStdSemaphoreData *sd)
  228. {
  229.   struct Node *n;
  230.  
  231.   while((n = RemHead(&sd->xssd_TypeList)))
  232.     FreeMem(n, ((struct XpkTypeNode *) n)->xtn_Size);
  233. }
  234.  
  235. void ClearMainPrefs(struct XpkPrefsSemaphore *sem)
  236. {
  237.   struct XpkStdSemaphoreData *sd = (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
  238.   if(sd->xssd_Buffer1)
  239.     FreeMem(sd->xssd_Buffer1, sd->xssd_Buffer1Size);
  240.   sem->xps_MainPrefs = 0;
  241.   sd->xssd_Buffer1Size = 0;
  242.   sd->xssd_Buffer1 = 0;
  243. }
  244.  
  245. void DoPrefsCreation(struct XpkPrefsSemaphore *sem)
  246. {
  247.   struct Library *iffparsebase;
  248.   struct ContextNode  *cn;
  249.   struct IFFHandle *iff;
  250.   ULONG prefsversion = 0;
  251.  
  252.   ObtainSemaphore(&sem->xps_Semaphore);
  253.  
  254.   ClearTypeList((struct XpkStdSemaphoreData *) sem->xps_PrefsData);
  255.   ClearMainPrefs(sem);
  256.  
  257.   if(!(iffparsebase = OpenLibrary("iffparse.library", 37)))
  258.     return;
  259.  
  260. #ifdef __MAXON__
  261.   IFFParseBase = iffparsebase;
  262. #endif
  263.  
  264.   if((iff = AllocIFF()))
  265.   {
  266.     if((iff->iff_Stream = Open("ENV:xpkmaster.prefs", MODE_OLDFILE)))
  267.     {
  268.       InitIFFasDOS(iff);
  269.       if(!OpenIFF(iff, IFFF_READ))
  270.       {
  271.     LONG a[] = { ID_PREF, ID_PRHD, ID_PREF, ID_XPKT, ID_PREF, ID_XPKM};
  272.     if(!StopChunks(iff, a, 3))
  273.     {
  274.       ULONG error = 0;
  275.  
  276.       while(!error)
  277.           {
  278.             if(ParseIFF(iff,IFFPARSE_SCAN))
  279.               break;
  280.  
  281.             cn = CurrentChunk(iff);
  282.  
  283.         switch(cn->cn_ID)
  284.         {
  285.         case ID_PRHD:
  286.           {
  287.             struct PrefHeader prh;
  288.             ReadChunkBytes(iff, &prh, sizeof(struct PrefHeader));
  289.             prefsversion = prh.ph_Version;
  290.     /* use this, when internal version is greater than one. In this
  291.        case the value is version of XPKT chunks */
  292.           } break;
  293.         case ID_XPKT:
  294.           {
  295.             struct XpkTypeNode *buf;
  296.         ULONG size;
  297.             size = cn->cn_Size + sizeof(struct Node) + sizeof(ULONG);
  298.             if((buf = (struct XpkTypeNode *) AllocMem(size, MEMF_PUBLIC|MEMF_CLEAR)))
  299.             {
  300.           struct XpkTypePrefs *pref = &buf->xtn_TypePrefs;
  301.  
  302.               ReadChunkBytes(iff, pref, cn->cn_Size);
  303.           CorrectAdr(&pref->xtp_NamePattern, pref);
  304.           CorrectAdr(&pref->xtp_FilePattern, pref);
  305.           CorrectAdr(&pref->xtp_TypeName, pref);
  306.           CorrectAdr(&pref->xtp_PackerData, pref);
  307.           buf->xtn_Node.ln_Name = pref->xtp_TypeName;
  308.           buf->xtn_Node.ln_Type = NT_USER;
  309.           buf->xtn_Size = size;
  310.           pref->xtp_PackerData->xtd_Memory = 0;
  311.           pref->xtp_PackerData->xtd_MemorySize = 0;
  312.           AddTail(&((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->xssd_TypeList, (struct Node *) buf);
  313.             }
  314.             else error = 1;
  315.           } break;
  316.         case ID_XPKM:
  317.           {
  318.         struct XpkMainPrefs *pref;
  319.         struct XpkStdSemaphoreData *sd =
  320.           (struct XpkStdSemaphoreData *) sem->xps_PrefsData;
  321.         struct XpkTypeData *p;
  322.  
  323.         ClearMainPrefs(sem);
  324.  
  325.             if((pref = (struct XpkMainPrefs *) AllocMem(cn->cn_Size, MEMF_PUBLIC|MEMF_CLEAR)))
  326.             {
  327.               ReadChunkBytes(iff, pref, cn->cn_Size);
  328.           CorrectAdr(&pref->xmp_DefaultType, pref);
  329.           p = pref->xmp_DefaultType;
  330.     /* XpkTypeData newer than version 0 may be incorrect, so set to 0 */
  331.           p->xtd_Version = 0;
  332.           p->xtd_Memory = 0;
  333.           p->xtd_MemorySize = 0;
  334.           sem->xps_MainPrefs = pref;
  335.                   sd->xssd_Buffer1Size = cn->cn_Size;
  336.                   sd->xssd_Buffer1 = (STRPTR) pref;
  337.         }
  338.         else error = 1;
  339.           } break;
  340.         }
  341.       }
  342.     }
  343.         CloseIFF(iff);
  344.       }
  345.       Close(iff->iff_Stream);
  346.     }
  347.     FreeIFF(iff);
  348.   }
  349.   CloseLibrary(IFFParseBase);
  350.   ReleaseSemaphore(&sem->xps_Semaphore);
  351. }
  352.  
  353. UBYTE CheckHex(STRPTR *data, LONG number)
  354. {
  355.   LONG num;
  356.   do
  357.   {
  358.     num = number;
  359.     while(num-- && isxdigit(*((*data)++)))
  360.       ;
  361.     if(++num)
  362.       return MATCHERR_PATTERN_INCORRECT;
  363.   } while(isxdigit(**data));
  364.   return 0;
  365. }
  366.  
  367. /* return 0, when pattern is valid */
  368. ULONG CheckBufPattern(STRPTR pattern)
  369. {
  370.   while(*pattern)
  371.   {
  372.     ULONG a;
  373.     STRPTR s;
  374.     
  375.     s = pattern;
  376.  
  377.     switch(*(pattern++))
  378.     {
  379.     case 'l': a = 1; break;
  380.     case 'h': a = 1; break;
  381.     case 'm': a = 1; break;
  382.     case 'v': a = 2; break;
  383.     case 'r': a = 4; break;
  384.     case 'g': a = 4; break;
  385.     case 's': a = 2; break;
  386.     case '|': a = 0; break;
  387.     default: return MATCHERR_PATTERN_INCORRECT; break;
  388.     }
  389.     if(a && CheckHex(&pattern, a))
  390.       return MATCHERR_PATTERN_INCORRECT;
  391.  
  392.     if((*s == 'm' && (pattern-s) > 5) ||
  393.     ((*s == 'l' || *s == 'h') && (pattern-s) > 9))
  394.       return MATCHERR_PATTERN_INCORRECT;
  395.     /* only word data for 'm' and longword for 'l' and 'h' + 1 '.' */
  396.   }
  397.  
  398.   return 0;
  399. }
  400.  
  401. UBYTE GetCharacter(STRPTR pattern)
  402. {
  403.   UBYTE i = 0, c;
  404.   ULONG size = 2;
  405.   while(size--)
  406.   {
  407.     i <<= 4;
  408.     if((c = toupper(*(pattern++))) >= 'A')
  409.       i += c + 10 - 'A';
  410.     else
  411.       i += c - '0';
  412.   }
  413.   return i;
  414. }
  415.  
  416. ULONG CheckPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
  417. {
  418.   STRPTR bufpos = buffer;
  419.   ULONG i;
  420.   UBYTE j, k;
  421.   STRPTR errpos, str;
  422.  
  423.   while(*pattern && *pattern != '|')
  424.   {
  425.     switch(*(pattern++))
  426.     {
  427.     case 'm':
  428.       i = strtoul(pattern, &errpos, 16);
  429.       pattern = errpos; /* first non hex char is next command */
  430.       if(i >= size)
  431.         return MATCHERR_BUFFER_TO_SHORT;
  432.       else
  433.         bufpos = buffer + i;
  434.       break;
  435.     case 'l':
  436.       i = strtoul(pattern, &errpos, 16);
  437.       pattern = errpos; /* first non hex char is next command */
  438.       if(fsize > i)
  439.         return MATCHERR_NO_SIZE_MATCH;
  440.       break;
  441.     case 'h':
  442.       i = strtoul(pattern, &errpos, 16);
  443.       pattern = errpos; /* first non hex char is next command */
  444.       if(fsize < i)
  445.         return MATCHERR_NO_SIZE_MATCH;
  446.       break;
  447.     case 'v':
  448.       while(isxdigit(*pattern))
  449.       {
  450.     j = GetCharacter(pattern); pattern += 2;
  451.         if(bufpos >= buffer + size)
  452.           return MATCHERR_BUFFER_TO_SHORT;
  453.     if(j != *(bufpos++))
  454.       return MATCHERR_NO_MATCH;
  455.       }
  456.       break;
  457.     case 'r':
  458.       while(isxdigit(*pattern))
  459.       {
  460.     errpos = buffer;
  461.     k = GetCharacter(pattern); pattern += 2;
  462.     j = GetCharacter(pattern); pattern += 2;
  463.         while(errpos < buffer + size)
  464.         {
  465.       if(*errpos >= k && *errpos <= j)
  466.         return MATCHERR_NO_MATCH;
  467.       ++errpos;
  468.     }
  469.       }
  470.       break;
  471.     case 'g':
  472.       while(isxdigit(*pattern))
  473.       {
  474.     k = GetCharacter(pattern); pattern += 2;
  475.     j = GetCharacter(pattern); pattern += 2;
  476.         if(bufpos >= buffer + size)
  477.           return MATCHERR_BUFFER_TO_SHORT;
  478.     if(*bufpos < k && *bufpos > j)
  479.       return MATCHERR_NO_MATCH;
  480.     ++bufpos;
  481.       }
  482.       break;
  483.     case 's':
  484.       bufpos = buffer;
  485.       while(isxdigit(*pattern))
  486.       {
  487.         str = pattern;
  488.     j = GetCharacter(str); str += 2;
  489.     while(bufpos < buffer + size && *bufpos != j)
  490.       ++bufpos;
  491.     if(*bufpos == j)
  492.     {
  493.       errpos = ++bufpos;
  494.           while(isxdigit(*str) && bufpos < buffer + size && 
  495.           GetCharacter(str) == *bufpos)
  496.           {
  497.         str += 2; ++bufpos;
  498.       }
  499.       if(!isxdigit(*str))
  500.         pattern = str;    /* exits while loop */
  501.       else
  502.         bufpos = errpos; /* reset buffer */
  503.         }
  504.         else
  505.       return MATCHERR_NO_MATCH;
  506.       }
  507.       break;
  508.     default: return MATCHERR_NO_MATCH; break;
  509.     }
  510.   }
  511.   return 0;
  512. }
  513.  
  514. ULONG MatchBufPattern(STRPTR pattern, STRPTR buffer, ULONG size, ULONG fsize)
  515. {
  516.   ULONG err = MATCHERR_NO_MATCH;
  517.  
  518.   if(CheckBufPattern(pattern))
  519.   {
  520. #ifdef DEBUG
  521.     Printf("MatchBufPattern: CheckBufPattern(%s) failed\n", pattern);
  522. #endif
  523.     return MATCHERR_PATTERN_INCORRECT;
  524.   }
  525.  
  526.   while(*pattern)
  527.   {
  528.     if(!(err = CheckPattern(pattern, buffer, size, fsize)))
  529.       return 0;
  530.     else /* search for next OR field or end of pattern */
  531.     {
  532.     
  533.       while(*pattern && *pattern != '|')
  534.         ++pattern;
  535.       if(*pattern == '|')
  536.         ++pattern;
  537.     }
  538.   }
  539.  
  540.   return err;
  541. }
  542.  
  543. ULONG MatchFileName(STRPTR pattern, STRPTR name)
  544. {
  545.   ULONG a, b = MATCHERR_NO_MATCH;
  546.   STRPTR buf;
  547.  
  548.   a = (strlen(pattern)<<1) + 10; // pattern match buffer
  549.  
  550.   if(!(buf = (STRPTR) AllocMem(a, MEMF_ANY)))
  551.     return MATCHERR_NO_MEMORY;
  552.  
  553.   if(ParsePatternNoCase(pattern, buf, a) >= 0 && MatchPatternNoCase(buf, name))
  554.     b = 0;
  555.  
  556.   FreeMem(buf, a);
  557.  
  558.   return b;
  559. }
  560.  
  561. struct XpkTypeData * __asm RecogFunc(register __a0 STRPTR buf,
  562. register __a1 STRPTR name, register __a2 STRPTR printname,
  563. register __d0 ULONG bufsize, register __d1 ULONG fullsize)
  564. {
  565.   struct XpkPrefsSemaphore *sem;
  566.   struct XpkTypePrefs *xp;
  567.   struct Node *n;
  568.  
  569.   if(!buf || !bufsize)
  570.     return 0;
  571.  
  572.   sem = (struct XpkPrefsSemaphore *) FindSemaphore(XPKPREFSSEMNAME);
  573.   /* I can do without ObtainSemaphore, because when I'm called here the
  574.   semaphore is owned already and surely exists */
  575.  
  576.   if(sem->xps_PrefsData)
  577.   {
  578.     for(n = ((struct XpkStdSemaphoreData *)sem->xps_PrefsData)->
  579.       xssd_TypeList.lh_Head; n->ln_Succ; n = n->ln_Succ)
  580.     {
  581.       xp = &((struct XpkTypeNode *) n)->xtn_TypePrefs;
  582.  
  583.       if((name && xp->xtp_Flags & XPKT_NamePattern) ||
  584.       xp->xtp_Flags & XPKT_FilePattern)
  585.       {
  586.         if(!(xp->xtp_Flags & XPKT_FilePattern) || !MatchBufPattern(
  587.         xp->xtp_FilePattern, buf, bufsize, fullsize))
  588.         {
  589.           if(!name || !(xp->xtp_Flags & XPKT_NamePattern) || !MatchFileName(
  590.           xp->xtp_NamePattern, name))
  591.       {
  592. #ifdef DEBUG
  593.             Printf("RecogFunc: matched '%s'\n", xp->xtp_TypeName);
  594. #endif
  595.             return xp->xtp_PackerData;
  596.       }
  597. #ifdef DEBUG
  598.           else
  599.             Printf("RecogFunc: no namematch '%s'\n", xp->xtp_TypeName);
  600. #endif
  601.         }
  602. #ifdef DEBUG
  603.         else
  604.           Printf("RecogFunc: no bufmatch '%s'\n", xp->xtp_TypeName);
  605. #endif
  606.       }
  607. #ifdef DEBUG
  608.       else
  609.         Printf("RecogFunc: no patterns '%s'\n", xp->xtp_TypeName);
  610. #endif
  611.     }
  612.   }
  613.  
  614.   if(sem->xps_MainPrefs)
  615.     return sem->xps_MainPrefs->xmp_DefaultType;
  616.  
  617.   return 0;
  618. }
  619.  
  620.